/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package battleshipgame.manager;

import battleshipgame.logic.AlreadyBombedException;
import battleshipgame.logic.ExitSignalException;
import battleshipgame.logic.InvalidInputException;
import battleshipgame.logic.Player;
import battleshipgame.ui.ConsoleIOManager;
import battleshipgame.ui.ConsoleIOManager.UserInputType;
import battleshipgame.ui.ConsoleIOManualInputHandler;
import java.util.ArrayList;

/**
 * @shaked
 * main logic class
 */
public class GameManager {
    
    public final static int MIN_NUM_PLAYERS = 2;
    public  final static int MAX_NUM_PLAYERS = 6;
    
    private int currentPlayerIndex;
    private int numOfPlayers ;
    //public Player[]  players;
    public ArrayList<Player> players;
    public  Player currentPlayer;
    public int totalPlayers;


    public GameManager()
    {
        totalPlayers= 0;
        currentPlayerIndex = 0;
        players = new ArrayList<Player>();
    }
    
    /*
     * @shaked
     * Main game method. runs until game is finished
     */
    public void startGame() throws ExitSignalException
    {

            UserInputType userInputType;
            boolean dataEnteredOK = false;
            while(!(dataEnteredOK))
                    {
                    userInputType = ConsoleIOManager.showWelcomeScreen();
                    if(userInputType == UserInputType.XML_INPUT)
                    {
                        try
                        {
                            XmlHandler.getGameDataFromXml(this);
                            dataEnteredOK = true;
                        }
                        catch (InvalidInputException e)
                        {
                            //TODO add exception logic here
                            ConsoleIOManager.printException(e);
                        }
                    }
                    else
                    {
                          if(userInputType == UserInputType.MANUAL_INPUT)
                          {
                              ConsoleIOManualInputHandler.getGameDataFromUser(this);
                              dataEnteredOK = true;
                         }
                    }
        }

            boolean bombedABattleship;
            while(!(gameFinished()))
                {

                removeDeadPlayers();
                
                currentPlayer = players.get(currentPlayerIndex);

                userInputType = UserInputType.NONE;
                ConsoleIOManager.declarCurrentPlayer(currentPlayer.getName());
                bombedABattleship = false;
                boolean shouldAdvanceToNextPlayer = false;
                
                // Player's turn

                //TODO added human computer logic here
                // if currentUser is COMPUTER dont enter the while below

                while(userInputType != UserInputType.BOMB_SQUARE && !(gameFinished()))
                    {
                    //TODO add check players status
                    Player opponent = ConsoleIOManager.getPlayerToAttack(currentPlayer, players);
                    ConsoleIOManager.printBoard(opponent.getName(), opponent.getBoard(), currentPlayer.getMarkBoard(opponent.getName()));
                    shouldAdvanceToNextPlayer = false;

                     userInputType = ConsoleIOManager.getCommandFromUser();

                     String coordiante =  ConsoleIOManager.getCoordianteFromUser();
                     try
                     {
                     switch(userInputType)
                     {
                         case MARK_SQUARE :
                             if(!(currentPlayer.getMarkBoard(opponent.getName()).IsMarked(coordiante)))
                             {
                               currentPlayer.markPlayer(opponent, coordiante);
                             }
                             break;
                         case CANCEL_MARK_SQUARE:
                             /*
                              * cancel mark only if marked
                              */
                             if(currentPlayer.getMarkBoard(opponent.getName()).IsMarked(coordiante))
                             {
                                currentPlayer.markPlayer(opponent, coordiante);
                             }
                             break;
                         case BOMB_SQUARE:
                             bombedABattleship = currentPlayer.bombPlayer(opponent, coordiante);
                             if (bombedABattleship)
                             {
                                 ConsoleIOManager.declareBombedABattleship();
                             }
                            else
                             {
                             shouldAdvanceToNextPlayer = true;
                            }
                             break;
                     }
                        }
                     catch(AlreadyBombedException e)
                     {
                          ConsoleIOManager.printException(e);
                     }
                     catch(InvalidInputException e)
                     {
                         //ConsoleIOManager.declareInvalidCoordiante();
                         ConsoleIOManager.printException(e);
                     }
                }

                if(!(gameFinished()) && shouldAdvanceToNextPlayer)
                {
                    advanceToNextPlayer();
                }
            }// end of while
            
            Player winner = getWinner();
            ConsoleIOManager.declareWinner(winner.getName());
            }


    public void removeDeadPlayers()
    {
             //check which players are dead
            for (int i = 0 ; i< players.size(); i++)
            {
                if(players.get(i).IsPlayerDead())
                {
                    if(i == currentPlayerIndex)
                    {
                        //if current player is dead. advance to next player
                        advanceToNextPlayer();
                    }
                    players.remove(i);
                }
          }
    }
    public int advanceToNextPlayer()
    {
         // advance to next player
         currentPlayerIndex++;
         if (currentPlayerIndex >= players.size())
         {
              currentPlayerIndex = 0;
         }
         return currentPlayerIndex;
    }
    public void addPlayer(Player player)
    {
        totalPlayers++;
        players.add(player) ;
    }


    public Player getPlayer(int i)
    {
        return this.players.get(i);
    }

    public static void main(String[] args){
             // initializes  the game
            GameManager gameManager = new GameManager();
            try
            {
                gameManager.startGame();
            }
            catch(ExitSignalException e)
            {
            //user has clicked on exit
            //TODO add exit echo message
                ConsoleIOManager.printExitMessage();
                
            }
    }

    private boolean gameFinished() {

        /*@shaked TODO add logic to check if game haven't finished yet
         * 
         */
        return (players.size() == 1);
    }

    private Player getWinner() {
        /*
         * @shaked TODO add get winner logic here
         */
        return players.get(0);
    }

    public ArrayList<Player> getPlayers() {
        return players;
    }
    
    

}
